package com.jeehentor.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeehentor.common.api.GenerateCommonAPI;
import com.jeehentor.common.api.vo.LoginUser;
import com.jeehentor.dto.MenuDTO;
import com.jeehentor.entity.SysMenu;
import com.jeehentor.entity.SysMenuMeta;
import com.jeehentor.entity.SysMenuPermission;
import com.jeehentor.entity.SysRoleMenu;
import com.jeehentor.system.mapper.SysMenuMapper;
import com.jeehentor.system.service.ISysMenuMetaService;
import com.jeehentor.system.service.ISysMenuPermissionService;
import com.jeehentor.system.service.ISysMenuService;
import com.jeehentor.system.service.ISysRoleMenuService;
import com.jeehentor.utils.SecurityUtil;
import com.jeehentor.vo.MenuVO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 系统菜单表 服务实现类
 * </p>
 *
 * @author wzd
 * @since 2024-04-01
 */
@Service
@RequiredArgsConstructor
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {

    private final ISysMenuMetaService sysMenuMetaService;

    private final ISysMenuPermissionService sysMenuPermissionService;

    private final SysMenuMapper sysMenuMapper;

    private final GenerateCommonAPI generateCommonAPI;
    private final ISysRoleMenuService sysRoleMenuService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addMenu(MenuDTO menuDTO) {
        // 添加菜单
        save(menuDTO);
        //添加元数据
        menuDTO.getMeta().setMenuId(menuDTO.getId());
        sysMenuMetaService.save(menuDTO.getMeta());
        //添加权限数据
        if(CollectionUtil.isNotEmpty(menuDTO.getPermissionList())){
            menuDTO.getPermissionList().forEach(permission ->{
                permission.setMenuId(menuDTO.getId());
                sysMenuPermissionService.save(permission);
            });

        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMenu(MenuDTO menuDTO) {
        //修改菜单主数据
        updateById(menuDTO);
        //修改菜单元数据
        sysMenuMetaService.updateById(menuDTO.getMeta());
        if(CollectionUtil.isNotEmpty(menuDTO.getPermissionList())){
            //删除菜单权限数据
            sysMenuPermissionService.remove(new QueryWrapper<SysMenuPermission>().lambda().eq(SysMenuPermission::getMenuId, menuDTO.getMeta().getMenuId()));
            menuDTO.getPermissionList().forEach(permission ->{
                permission.setMenuId(menuDTO.getMeta().getMenuId());
                //保存菜单权限数据
                sysMenuPermissionService.save(permission);
            });
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteMenu(SysMenu sysMenu) {
        // 根据菜单ID移除菜单
        removeById(sysMenu);
        // 根据菜单ID移除菜单权限
        sysMenuPermissionService.remove(new QueryWrapper<SysMenuPermission>().lambda().eq(SysMenuPermission::getMenuId,sysMenu.getId()));
        // 根据菜单ID移除菜单元数据
        sysMenuMetaService.removeById(sysMenu.getId());
        //删除角色菜单配置
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().lambda().eq(SysRoleMenu::getMenuId,sysMenu.getId()));
    }


    @Override
    public List<MenuVO> menuList(MenuDTO menuDTO) {
        //查询所有菜单
        LambdaQueryWrapper<SysMenu> sysMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysMenuLambdaQueryWrapper.like(StringUtils.isNotBlank(menuDTO.getTitle()),SysMenu::getTitle, menuDTO.getTitle());
        List<SysMenu> list = list(sysMenuLambdaQueryWrapper);
        //递归处理菜单
        return buildTree(list);
    }

    @Override
    public MenuVO menuDetail(SysMenu sysMenu) {
        //查询菜单详情
        SysMenu menu = getById(sysMenu.getId());
        if(ObjectUtil.isNotNull(menu)){
            //查询菜单元数据
            SysMenuMeta menuMeta = sysMenuMetaService.getOne(new QueryWrapper<SysMenuMeta>().lambda().eq(SysMenuMeta::getMenuId,menu.getId()));
            //查询菜单权限
            List<SysMenuPermission> menuPermissionList = sysMenuPermissionService.list(new QueryWrapper<SysMenuPermission>().lambda().eq(SysMenuPermission::getMenuId,menu.getId()));
            //封装返回数据
            MenuVO menuVO = new MenuVO();
            BeanUtils.copyProperties(menu,menuVO);
            menuVO.setMeta(menuMeta);
            menuVO.setPermissionList(menuPermissionList);
            return menuVO;
        }
        return null;
    }

    @Override
    public List<MenuVO> getRouter() {
        LoginUser currentUser = SecurityUtil.getCurrentUser();
        List<String> roles = currentUser.getRoles();
        if(roles.contains("admin")){
            //超级管理员，查询所有菜单
            LambdaQueryWrapper<SysMenu> sysMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
            sysMenuLambdaQueryWrapper.eq(SysMenu::getStatus,'1');
            List<SysMenu> list = list(sysMenuLambdaQueryWrapper);
            //递归处理菜单
            return buildTreeAndDetail(list);
        }else {
            //普通用户，查询当前用户所拥有的菜单
            List<SysMenu> menuList = sysMenuMapper.getRouter(currentUser.getId());
            //递归处理菜单
            return buildTreeAndDetail(menuList);
        }
    }
    private List<MenuVO> buildTreeAndDetail(List<SysMenu> list) {
        // 用来存储菜单ID和对应的菜单对象，方便通过ID快速查找菜单
        Map<String, MenuVO> menuMap = new HashMap<>();

        // 遍历菜单列表，将菜单对象放入map中
        for (SysMenu sysMenu : list) {
            //动态页面参数
            String pageId = generateCommonAPI.getPageId(sysMenu.getId());
            if(StringUtils.isNotBlank(pageId)){
                HashMap<String, String> stringHashMap = new HashMap<>();
                stringHashMap.put("pageId",pageId);
                sysMenu.setProps(stringHashMap);
            }
            MenuVO menuVO = new MenuVO();
            SysMenuMeta menuMeta = sysMenuMetaService.getOne(new QueryWrapper<SysMenuMeta>().lambda().eq(SysMenuMeta::getMenuId,sysMenu.getId()));
            //查询菜单权限
            List<SysMenuPermission> menuPermissionList = sysMenuPermissionService.list(new QueryWrapper<SysMenuPermission>().lambda().eq(SysMenuPermission::getMenuId,sysMenu.getId()));
            BeanUtils.copyProperties(sysMenu,menuVO);
            menuVO.setMeta(menuMeta);
            menuVO.setPermissionList(menuPermissionList);
            menuMap.put(sysMenu.getId(), menuVO);
        }

        // 构建菜单树
        List<MenuVO> menuTree = new ArrayList<>();
        for (SysMenu sysMenu : list) {
            // 如果当前菜单没有父菜单，即为根菜单
            if (sysMenu.getParentId() == null) {
                menuTree.add(menuMap.get(sysMenu.getId()));
            } else {
                // 如果有父菜单，则将其添加到父菜单的子菜单列表中
                MenuVO parentMenu = menuMap.get(sysMenu.getParentId());
                if (parentMenu != null) {
                    parentMenu.addChild(menuMap.get(sysMenu.getId()));
                }
            }
        }

        return menuTree;
    }

    @Override
    public List<MenuVO> buildTree(List<SysMenu> list) {
        // 用来存储菜单ID和对应的菜单对象，方便通过ID快速查找菜单
        Map<String, MenuVO> menuMap = new HashMap<>();

        // 遍历菜单列表，将菜单对象放入map中
        for (SysMenu sysMenu : list) {
            MenuVO menuVO = new MenuVO();
            BeanUtils.copyProperties(sysMenu,menuVO);
            menuMap.put(sysMenu.getId(), menuVO);
        }

        // 构建菜单树
        List<MenuVO> menuTree = new ArrayList<>();
        for (SysMenu sysMenu : list) {
            // 如果当前菜单没有父菜单，即为根菜单
            if (sysMenu.getParentId() == null) {
                menuTree.add(menuMap.get(sysMenu.getId()));
            } else {
                // 如果有父菜单，则将其添加到父菜单的子菜单列表中
                MenuVO parentMenu = menuMap.get(sysMenu.getParentId());
                if (parentMenu != null) {
                    parentMenu.addChild(menuMap.get(sysMenu.getId()));
                }else {
                    SysMenu byId = getById(sysMenu.getParentId());
                    if(byId == null){
                        // 如果父菜单不存在，则创建一个空的父菜单对象，并将当前菜单添加到该空父菜单的子菜单列表中
                        MenuVO emptyParentMenu = new MenuVO();
                        emptyParentMenu.addChild(menuMap.get(sysMenu.getId()));
                        menuTree.add(emptyParentMenu);
                    }else {
                        MenuVO emptyParentMenu = new MenuVO();
                        BeanUtils.copyProperties(byId,emptyParentMenu);
                        emptyParentMenu.addChild(menuMap.get(sysMenu.getId()));
                        menuTree.add(emptyParentMenu);
                    }
                }
            }
        }

        return menuTree;
    }

    @Override
    public MenuDTO existMenu(String parentId, String name){
        LambdaQueryWrapper<SysMenu> sysMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysMenuLambdaQueryWrapper.eq(SysMenu::getParentId,parentId);
        sysMenuLambdaQueryWrapper.eq(SysMenu::getName,name);
        SysMenu menu = this.getOne(sysMenuLambdaQueryWrapper);
        if(ObjectUtil.isNotNull(menu)){
            //查询菜单元数据
            SysMenuMeta menuMeta = sysMenuMetaService.getOne(new QueryWrapper<SysMenuMeta>().lambda().eq(SysMenuMeta::getMenuId,menu.getId()));
            //查询菜单权限
            List<SysMenuPermission> menuPermissionList = sysMenuPermissionService.list(new QueryWrapper<SysMenuPermission>().lambda().eq(SysMenuPermission::getMenuId,menu.getId()));
            //封装返回数据
            MenuDTO menuDTO = new MenuDTO();
            BeanUtils.copyProperties(menu,menuDTO);
            menuDTO.setMeta(menuMeta);
            menuDTO.setPermissionList(menuPermissionList);
            return menuDTO;
        }
        return null;
    }

}
